﻿using Sidvall.Serialization;
using Sidvall.WorkItemManager.Data;
using System.Threading.Tasks;

namespace Sidvall.WorkItemManager.Workflow.WorkItems
{
    public class TestWorkItemProvider : WorkItemProviderBase
    {
        #region Public Members

        #region ExecuteAsync

        public override async Task<WorkItemResult> ExecuteAsync()
        {
            // Parse this.Context and this.ExecutionContext
            DeserializeContext();

            // Do task
            var random = new System.Random();
            for (int i = 0; i < this.ContextItem.LoopCount; i++)
            {
                await Task.Delay(1000).ConfigureAwait(false);
                var executionCompletionPercentage = (byte)((i + 1) * 100 / this.ContextItem.LoopCount);
                var context = "Phase " + (i + 1).ToString(System.Globalization.CultureInfo.InvariantCulture) + ": " + executionCompletionPercentage.ToString() + "%";

                // Update status so that the progress can be shown to users. When calling this method
                // the IsCanceled flag can be set to indicate that the task should abort.
                await UpdateExecutionContextAsync(context, executionCompletionPercentage).ConfigureAwait(false);

                // Check if the cancel-flag is set. Abort if so is the case.
                if (this.IsCanceled)
                    return new WorkItemResult(WorkItemResultType.Canceled, "I have been canceled.");

                // Update sensors. When calling this method
                // the IsCanceled flag can be set to indicate that the task should abort.
                this.SensorValues.UpdateSensor("Temperature", random.Next(0, 100).ToString(), System.DateTime.UtcNow);
                this.SensorValues.UpdateSensor("Pressure", random.Next(0, 100).ToString(), System.DateTime.UtcNow);
                this.SensorValues.UpdateSensor("Online", random.Next(0, 1).ToBoolean(false).ToString(), System.DateTime.UtcNow);
                await UpdateSensorsAsync().ConfigureAwait(false);

                // Check if the cancel-flag is set. Abort if so is the case.
                if (this.IsCanceled)
                    return new WorkItemResult(WorkItemResultType.Canceled, "I have been canceled.");
            }

            // Return result
            return new WorkItemResult(WorkItemResultType.Ok, "I have done nothing at all except a bunch of Task.Delay.");
        }

        #endregion
        #region GetSensorsAsync

        public override Task<SensorCollection> GetSensorsAsync()
        {
            var sensors = new SensorCollection();
            sensors.Add("Temperature", "The outdoor temperature");
            sensors.Add("Pressure", "The outdoor pressure");
            sensors.Add("Online", "Is the server online");
            return Task.FromResult(sensors);
        }

        #endregion

        #endregion
        #region Private Members

        private Sidvall.WorkItemManager.Workflow.WorkItems.WorkItemContext ContextItem { get; set; }

        private void DeserializeContext()
        {
            this.ContextItem = Sidvall.WorkItemManager.Workflow.WorkItems.WorkItemContext.Deserialize(this.Context);
        }

        #endregion
    }
}
